<?php
declare(strict_types=1);

/**
 * Created by PhpStorm.
 * User: 小灰灰
 * Date: 2021-06-02
 * Time: 上午10:40:48
 * Info: 基础模型，初始化
 */

namespace app\common\model;

use think\Model;
use think\model\concern\SoftDelete;
use think\Collection;
use think\Paginator;

class TimeInit extends Model
{

    public const PAGE_LIMIT = 15;

    /**
     * 自动时间戳类型
     * @var bool|string
     */
    protected $autoWriteTimestamp = true;

    /**
     * 添加时间字段名
     * @var bool|string
     */
    protected $createTime = 'create_time';

    /**
     * 更新时间字段名
     * @var bool|string
     */
    protected $updateTime = 'update_time';

    /**
     * 软删除
     */
    use SoftDelete;

    /**
     * 软删除默认值
     * @var int
     */
    protected $defaultSoftDelete = 0;

    /**
     * 软删除字段名
     * @var bool|string
     */
    protected $deleteTime = false;

    /**
     * 返回layui的table所需要的格式
     *
     * @param array    $params 查询参数
     * @param int|null $limit  每页数量
     *
     * @return string JSON格式数据
     */
    public function tableData(array $params, ?int $limit = null): string
    {
        $limit = $limit ?? (int)($params['limit'] ?? self::PAGE_LIMIT);
        $limit = max(1, min($limit, 1000)); // 限制每页最大数量

        $tableWhere = $this->tableWhere($params);

        /** @var Paginator $paginator */
        $paginator = $this->field($tableWhere['field'])->where($tableWhere['where'])->order($tableWhere['order'])->paginate($limit);

        // 格式化数据
        $data = $this->tableFormat($paginator->getCollection());

        $result = [
            'code'  => 0,
            'msg'   => '',
            'count' => $paginator->total(),
            'data'  => $data->toArray()
        ];

        return json_encode($result, JSON_UNESCAPED_UNICODE);
    }

    /**
     * 根据输入的查询条件，返回所需要的where
     *
     * @param array $params 查询参数
     *
     * @return array 查询条件数组
     */
    protected function tableWhere(array $params): array
    {
        $where = function ($query) use ($params) {
            // 子类可以重写此方法添加具体条件
        };

        return [
            'where' => $where,
            'field' => '*',
            'order' => []
        ];
    }

    /**
     * 根据查询结果，格式化数据
     *
     * @param Collection $list 数据集合
     *
     * @return Collection 格式化后的数据集合
     */
    protected function tableFormat(Collection $list): Collection
    {
        return $list;
    }

    /**
     * 获取分页数据（更灵活的方法）
     *
     * @param array    $params 查询参数
     * @param int|null $limit  每页数量
     *
     * @return array 分页数据
     */
    public function getPageData(array $params, ?int $limit = null): array
    {
        $limit = $limit ?? (int)($params['limit'] ?? self::PAGE_LIMIT);
        $limit = max(1, min($limit, 1000));

        $tableWhere = $this->tableWhere($params);

        /** @var Paginator $paginator */
        $paginator = $this->field($tableWhere['field'])->where($tableWhere['where'])->order($tableWhere['order'])->paginate($limit);

        return [
            'list'         => $this->tableFormat($paginator->getCollection())->toArray(),
            'total'        => $paginator->total(),
            'per_page'     => $paginator->listRows(),
            'current_page' => $paginator->currentPage(),
            'last_page'    => $paginator->lastPage()
        ];
    }

    /**
     * 批量插入数据
     *
     * @param array $dataList 数据列表
     * @param bool  $replace  是否替换
     *
     * @return int 插入的记录数
     */
    public function batchInsert(array $dataList, bool $replace = false): int
    {
        if (empty($dataList)) {
            return 0;
        }

        return $replace ? $this->saveAll($dataList, true) : $this->saveAll($dataList);
    }

    /**
     * 获取缓存数据
     *
     * @param string   $key      缓存键
     * @param callable $callback 回调函数
     * @param int      $expire   过期时间（秒）
     *
     * @return mixed
     */
    public function getCacheData(string $key, callable $callback, int $expire = 3600)
    {
        $cacheKey = static::class.':'.$key;
        $data     = cache($cacheKey);

        if ($data === null) {
            $data = $callback();
            cache($cacheKey, $data, $expire);
        }

        return $data;
    }

    /**
     * 清除缓存
     *
     * @param string $key 缓存键
     *
     * @return bool
     */
    public function clearCache(string $key): bool
    {
        $cacheKey = static::class.':'.$key;

        return cache($cacheKey, null);
    }
}
